%{
package main

import (
    "fmt"
    "text/scanner"
    "strings"
)

%}

%union {
    strValue string
    
}

// 定义 token
%token <strValue> FUNCTION METRIC RANGE BY
%type <strValue> expression function_call grouping

%start expression


%%

// 语法规则
expression: function_call grouping { 
    fmt.Printf("Function: %s, Grouping: %s\n", $1, $2) 
}

function_call: FUNCTION '(' METRIC RANGE ')' {
    $$ =  fmt.Sprintf("%s(%s%s)", $1, $3, $4)
}

grouping: BY '(' METRIC ')' {
    $$ =  fmt.Sprintf("by (%s)", $3)
}

%%

type Lexer struct{
    scanner.Scanner
    result interface{}
}

func (l *Lexer)Lex(lval *yySymType) int {
    if tok := l.Scan(); tok != scanner.EOF {
        switch string(tok) {
        case "avg":
            return FUNCTION
        case "cpu_usage":
            return METRIC
        case "instance":
            return METRIC
        case "[5m]":
            return RANGE
        case "by":
            return BY
        }
    }
    return 0 // EOF
}

func (l *Lexer) Error(e string) {
    panic(e)
}

func main() {
    input := "avg(cpu_usage [ 5m]) by (instance)"
    l := new(Lexer)
    l.Init(strings.NewReader(input))
    l.Whitespace ^= 1<<'\n' | 1<<' ' // 忽略空白字符

    yyParse(l) // 调用生成的解析器
    fmt.Println("Parsed successfully!")
}